/**   
* @Title: MetadataUpdateService.java 
* @Package com.medsoft.logpool.core 
* @Description: TODO(用一句话描述该文件做什么) 
* @author zjhua@hundsun.com   
* @date 2016年7月12日 上午9:15:32 
* @version V1.0   
*/ 
package com.medsoft.perfstat.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cyl.kernel.BusinessException;
import com.cyl.kernel.DBContextHolder;
import com.medsoft.perfstat.dao.MetadataDAO;
import com.medsoft.perfstat.dao.PerfStatInsertDAO;
import com.medsoft.perfstat.pojo.AppSnap;
import com.medsoft.perfstat.pojo.Apps;
import com.medsoft.perfstat.pojo.ISGlobalStatus;
import com.medsoft.perfstat.pojo.ISGlobalVariable;
import com.medsoft.perfstat.pojo.ISIndexStatistics;
import com.medsoft.perfstat.pojo.ISTableStatistics;
import com.medsoft.perfstat.pojo.InnodbBufferPoolStats;
import com.medsoft.perfstat.pojo.OsInfo;
import com.medsoft.perfstat.pojo.PSEventsStatementsSummaryByDigest;
import com.medsoft.perfstat.pojo.PSEventsWaitsSummaryGlobalByEventName;
import com.medsoft.perfstat.pojo.PSTableIOWaitsSummaryByIndexUsage;
import com.medsoft.perfstat.pojo.PSTableIOWaitsSummaryByTable;
import com.medsoft.perfstat.pojo.PSTableLockWaitsSummaryByTable;
import com.medsoft.perfstat.pojo.SlaveStatus;
import com.medsoft.perfstat.pojo.SlowQueryLogDigest;

/**
 * @author zjhua
 *
 */
@Service
public class PerfStatCollectService {
	
	static final Logger logger = LoggerFactory.getLogger(PerfStatCollectService.class);
	
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	@Autowired
	private PerfStatSrcService perfStatSrcService;
	
	@Autowired
	private PerfStatInsertService perfStatInsertService;
	
	@Autowired
	private PerfStatPurgeService perfStatPurgeService;
	
	@Autowired
	private MetadataDAO metadataDAO;
	
	@Autowired
	private PerfStatInsertDAO perfStatInsertDAO;
	
	public void collectPerfStat(String appname,int snapInterval) {
		AppSnap appSnap = new AppSnap();
		String logTime = sdf.format(new Date());
		for(Apps app : metadataDAO.queryApps(appname,snapInterval)) {
			logger.info("开始采集服务器[" + app.getAppname() + "],[" + app.getHostname() + ":" + app.getPort() + "],[调度间隔: + " + app.getSnapInterval() + "分钟]的信息！");
			try {
				int snapId = metadataDAO.getNextAppSnap(app);
				appSnap.setAppname(app.getAppname());
				appSnap.setHostname(app.getHostname());
				appSnap.setSnapId(snapId);
				appSnap.setLogTime(logTime);
				
				DBContextHolder.setTargetDataSource(app.getAppname() + "_ds");
				List<ISGlobalStatus> listA = perfStatSrcService.queryISGlobalStatus(app);
				List<ISGlobalVariable> listB = perfStatSrcService.queryISGlobalVariables(app);
				List<ISIndexStatistics> listC = perfStatSrcService.queryISIndexStatistics();
				List<ISTableStatistics> listD = perfStatSrcService.queryISTableStatistics();
				List<PSEventsStatementsSummaryByDigest> listE = perfStatSrcService.queryPSEventsStatementsSummaryByDigest();
				List<PSTableIOWaitsSummaryByIndexUsage> listG = perfStatSrcService.queryPSTableIOWaitsSummaryByIndexUsage();
				List<PSTableIOWaitsSummaryByTable> listH = perfStatSrcService.queryPSTableIOWaitsSummaryByTable();
				List<PSTableLockWaitsSummaryByTable> listI = perfStatSrcService.queryPSTableLockWaitsSummaryByTable();
				List<PSEventsWaitsSummaryGlobalByEventName> listF = perfStatSrcService.queryPSEventsWaitsSummaryGlobalByEventName();
				
				List<SlaveStatus> listJ = perfStatSrcService.querySlaveStatus();
				List<InnodbBufferPoolStats> listK = perfStatSrcService.queryInnodbBufferPoolStats();
				ISGlobalStatus globalStatusCpu = new ISGlobalStatus();
				ISGlobalStatus globalStatusMem = new ISGlobalStatus();
				ISGlobalStatus globalStatusMySQLStartTime = new ISGlobalStatus();
				try {
					String[] mysqlOsInfo = perfStatSrcService.getMySQLOSInfo(app);
					String cpuTime = mysqlOsInfo[1];
					String memoryUsed = mysqlOsInfo[0];
					String mysqlStartTime = mysqlOsInfo[2];
					globalStatusCpu.put("cpu_time", cpuTime);
					globalStatusMem.put("memory_used", memoryUsed);
					globalStatusMySQLStartTime.put("mysql_start_time", mysqlStartTime);
				} catch (BusinessException e) {
					logger.error("获取MySQL进程CPU和内存信息出现异常！",e);
					globalStatusCpu.put("cpu_time", "00:00");
					globalStatusMem.put("memory_used", "-1");
					globalStatusMySQLStartTime.put("mysql_start_time", "-1");
					appSnap.setExecResultInfo("获取MySQL进程CPU和内存信息出现异常！");
				}
				listA.add(globalStatusCpu);
				listA.add(globalStatusMem);
				listA.add(globalStatusMySQLStartTime);
				
				OsInfo osInfo = new OsInfo();
				osInfo.setAppSnap(appSnap);
				try {
					long osUptime = perfStatSrcService.getOSUptime(app);
					osInfo.setUpTime(osUptime);
				} catch (BusinessException e) {
					logger.error("获取OS启动时间出现异常！",e);
					osInfo.setUpTime(-1);
					appSnap.setExecResultInfo("获取OS启动时间出现异常！");
				}
				
				try {
					String[] osCpuTime = perfStatSrcService.getOSCPUTime(app);
					long idleTime = Long.valueOf(osCpuTime[3]);
					osInfo.setIdleTime(idleTime);
					long systemTime = Long.valueOf(osCpuTime[2]);
					osInfo.setSystemTime(systemTime);
					long ioTime = Long.valueOf(osCpuTime[4]);
					osInfo.setIoTime(ioTime);
					long userTime = Long.valueOf(osCpuTime[0]);
					osInfo.setUserTime(userTime);
				} catch (BusinessException e) {
					logger.error("获取OS cpu使用率出现异常！",e);
					osInfo.setIdleTime(-1);
					osInfo.setSystemTime(-1);
					osInfo.setIoTime(-1);
					osInfo.setUserTime(-1);
					appSnap.setExecResultInfo("获取OS cpu使用率出现异常！");
				}
				
				try {
					int cores = perfStatSrcService.getOSCPUCount(app);
					osInfo.setCores(cores);
				} catch (BusinessException e) {
					logger.error("获取OS cpu数量出现异常！",e);
					osInfo.setCores(-1);
					appSnap.setExecResultInfo("获取OS cpu数量出现异常！");
				}
				
				try {
					String[] osMemInfo = perfStatSrcService.getOSMemInfo(app);
					long memTotal = Long.valueOf(osMemInfo[0]);
					osInfo.setMemTotal(memTotal);
					long memUsed = memTotal - Long.valueOf(osMemInfo[1]);
					osInfo.setMemUsed(memUsed);
					long swapTotal = Long.valueOf(osMemInfo[2]);
					osInfo.setSwapTotal(swapTotal);
					long swapUsed = swapTotal - Long.valueOf(osMemInfo[3]);
					osInfo.setSwapUsed(swapUsed);
				} catch (BusinessException e) {
					logger.error("获取OS内存信息出现异常！",e);
					osInfo.setMemTotal(-1);
					osInfo.setMemUsed(-1);
					osInfo.setSwapTotal(-1);
					osInfo.setSwapUsed(-1);
					appSnap.setExecResultInfo("获取OS内存信息出现异常！");
				}
				
				//rotate slow log
				String oldFileName = perfStatSrcService.disableSlowlogAndGetName(app);
				String rotateFileName = perfStatSrcService.renameSlowQueryLog(app, oldFileName);
				perfStatSrcService.enableSlowLog();
				
				//parse slow log
				String analyzedFileName = perfStatSrcService.parseSlowQueryLog(app, rotateFileName);
				List<SlowQueryLogDigest> listL = perfStatSrcService.getSlowQueryLogSummary(app, analyzedFileName);
				perfStatSrcService.removeOldFile(app,rotateFileName,analyzedFileName);
				
				perfStatInsertService.insertISGlobalStatus(appSnap,listA);
				perfStatInsertService.insertISGlobalVariables(appSnap,listB);
				perfStatInsertService.insertISIndexStatistics(appSnap,listC);
				perfStatInsertService.insertISTableStatistics(appSnap,listD);
				perfStatInsertService.insertPSEventsStatementsSummaryByDigest(appSnap,listE);
				perfStatInsertService.insertPSTableIOWaitsSummaryByIndexUsage(appSnap,listG);
				perfStatInsertService.insertPSTableIOWaitsSummaryByTable(appSnap,listH);
				perfStatInsertService.insertPSTableLockWaitsSummaryByTable(appSnap,listI);
				perfStatInsertService.insertPSEventsWaitsSummaryGlobalByEventName(appSnap,listF);
				
				perfStatInsertService.insertSlaveStatus(appSnap,listJ);
				perfStatInsertService.insertInnodbBufferPoolStats(appSnap,listK);
				perfStatInsertService.insertOsInfo(osInfo);
				
				perfStatInsertService.insertSlowQuerySummary(appSnap,listL);
				
				appSnap.trim256();
				perfStatInsertDAO.insertAppSnaps(appSnap);
			} catch (Exception e) {
				logger.error("服务器[" + app.getAppname() + "],[" + app.getHostname() + ":" + app.getPort() + "出现异常,请检查配置是否正确、网络是否通畅！",e);
				logger.info("开始回滚该服务器所有已提交事务。。。。");
				perfStatPurgeService.deleteOldLog(appSnap);
				logger.info("开始已提交事务回滚完成!");
			}
		}
	}
}
